import random
import struct
from PIL import Image, ImageDraw

from gui import main_window


def read_uv_index(fp):
    start = 0x16840
    size = 0x5e8
    cnt = size // 4
    fp.seek(start)
    r = struct.iter_unpack('<i', fp.read(size))
    return [i[0]//2 for i in r]


def read_uv_cnt(fp):
    start = 0x16240
    size = 0x5e8
    cnt = size // 4
    fp.seek(start)
    r = struct.iter_unpack('<i', fp.read(size))
    return [i[0] for i in r]


def read_drawable_start(fp):
    start = 0x16e40
    size = 0x5e8
    cnt = size // 4
    fp.seek(start)
    r = struct.iter_unpack('<i', fp.read(size))
    return [i[0]//3 for i in r]


def read_drawable_cnt(fp):
    start = 0x17440
    size = 0x5e8
    cnt = size // 4
    fp.seek(start)
    r = struct.iter_unpack('<i', fp.read(size))
    return [i[0]//3 for i in r]


def read_drawable_data(fp):
    start = 0xa7c00
    size = 0x8fa6
    cnt = size // 2 // 3
    fp.seek(start)
    r = struct.iter_unpack('<H', fp.read(size))     # H:uint16
    return [(next(r)[0], next(r)[0], next(r)[0]) for _ in range(cnt)]


def show_uv():
    target_dir = './chuixue_3/chuixue_3.moc3'
    pos_start = 0x9d580
    data_size = 0xa658
    data_cnt = data_size // 4

    ca_origin = (2400, 3090)
    ca_size = (4800, 6180)

    tx_size = (2048, 2048)
    im = Image.new('RGBA', tx_size, (255, 255, 255, 0))

    def point(pos: tuple):
        im.putpixel(pos, (168, 255, 255, 255))

    uv_buf = []
    with open(target_dir, 'rb') as fp:
        uv_index = read_uv_index(fp)
        uv_cnt = read_uv_cnt(fp)
        fp.seek(pos_start)
        data = fp.read(data_size)
        r = struct.iter_unpack("<f", data)
        # print([next(r)[0] for _ in range(10)])
        draw = ImageDraw.Draw(im)
        for _ in range(data_cnt // 2):
            xy = (int(next(r)[0] * tx_size[0]), int(next(r)[0] * tx_size[1]))
            point(xy)
            uv_buf.append(xy)

        # for idx, cnt in zip(uv_index, uv_cnt):
        #     if idx < 1:
        #         c = (128, 128, 255, 255)
        #     else:
        #         c = (255, 255, 168, 255)
        #     for i in range(idx+1, idx+cnt):
        #         draw.line((uv_buf[i-1], uv_buf[i]), c, 1)
        # filling
        dr_start = read_drawable_start(fp)
        dr_cnt = read_drawable_cnt(fp)
        dr_data = read_drawable_data(fp)
        for idx, cnt, base in zip(dr_start, dr_cnt, uv_index):
            rc = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), 127)
            # base = uv_index
            for j in range(cnt):
                xx, yy, zz = dr_data[idx + j]
                draw.polygon((uv_buf[base + xx], uv_buf[base + yy], uv_buf[base + zz]), rc, (255, 255, 255, 255))

    im.show()


def read_pos_data_idx(fp):
    start = 0xA7BD8
    size = 0x8FA6
    cnt = size // 4
    fp.seek(start)
    r = struct.iter_unpack('<i', fp.read(size))
    return [i[0] for i in r]


def read_pos_data(fp):
    start = 0x24bac
    size = 0x77214
    cnt = size // 4
    fp.seek(start)
    r = struct.iter_unpack('<f', fp.read(size))
    return [i[0] for i in r]


def show_pos():
    target_dir = './chuixue_3/chuixue_3.moc3'



def main():
    # show_uv()
    # show_pos()
    main_window.start_main_window()


if __name__ == '__main__':
    main()
